#include "highLeveCommSM.h"
#include <stdlib.h>
/*
 * HLCstateMachine       |     HandShakeMachine
 *                       |
 * SEND_FRAME            |
 *  |                    |
 *  V                    |
 * HLCstateMachineOnInit |
 * |                     |
 * V                     |
 * HLCTransactionState   |
 * |
 * +------------------------->  SEND_PACKET
 *                       |           |
 * +--------------OK----------------+
 * |
 * V
 * HandshakeMachineTesterOkState
 * |
 * V
 * stateMachineDispatcher(SEND_OK)
 * */

void HLCstateMachineOnInit(void* me,StateHandler initState,uint8_t* buffer,uint32_t len,uint8_t dst){
	HighLevelCommSM* temp=(HighLevelCommSM*)me;
	temp->buffer=buffer;
	temp->len=len;
	temp->dst=dst;
	stateMachineOnInit(me,initState);
}
void HLCTransactionToTransaction(void*me){
	HighLevelCommSM* temp=(HighLevelCommSM*)me;
	temp->msgCounter++;
}
StateOutcome HLCTransactionState(void* me,const Event* e){
	HighLevelCommSM* temp=(HighLevelCommSM*) me;
	uint32_t lenTemp;
	switch(e->signature){
	case INIT_CODE:
		temp->msgCounter=0;
		lenTemp=temp->len%8;
		if (lenTemp==0)
			temp->maxMsg=temp->len/8;
		else
			temp->maxMsg=(len/8)+1;
	case ENTRY_CODE:
		temp->super->passageAction=NULL;
		HLCHSMInit(temp->handler,temp->buffer[temp->msgCounter]); //inizializzazione al di fuori dello state machine framework
		stateMachineOnInit((void*) &temp->handler, HandshakeMachineTesterTXsentState); //triggera invio dati
		temp->super->passageAction=NULL;
		return EVENT_HANDLED;
	case HIGH_LEVEL_SEND_OK_CODE:
		if (temp->msgCounter<temp->maxMsg)
			temp->super->passageAction=HLCTransactionToTransaction;
		else
		{
			temp->super->state=HLCOkState;
			temp->super->passageAction=NULL;
		}
		return EVENT_CHANGED;
	case HIGH_LEVEL_SEND_FAIL_CODE:
		temp->super->state=HLCFailState;
		temp->super->passageAction=NULL;
		return EVENT_CHANGED;
	default:
		return EVENT_IGNORED;
	}
}
StateOutcome HLCOkState(void* me,const Event* e){
	HighLevelCommSM* temp=(HighLevelCommSM*) me;
	switch (e->signature)
	{
	default:
		temp->onOK(temp->caller);
	}
	return EVENT_HANDLED;
}
StateOutcome HLCFailState(void* me,const Event* e){
	HighLevelCommSM* temp=(HighLevelCommSM*) me;
	switch (e->signature)
	{
	default:
		temp->onFail(temp->caller);
	}
	return EVENT_HANDLED;
}
